[t:/]$ 지식_

apache module pre, post, proxy dev.

2015/06/26

아파치 모듈 개발시 프리 프로세싱, 포스트 프로세싱, 프락시 등을 구현하기.

아파치 모듈 개발을 하다보면 이런 것을 만들고 싶다. 모듈은 다음과 같이 있다.

아파치 모듈 A

아파치 모듈 B

A 모듈은 기존 서비스 모듈이다.

B 모듈은 신규 추가 모듈이다. B모듈은 A 모듈 앞에서 프리 프로세싱을 할 수도 있고 A모듈 뒤에서 포스트 프로세싱을 하는 것을 원할 수도 있다.

또는 A 모듈 앞에서 그냥 투명 프락시 처럼 동작하고 싶을 때도 있다. 조건 분기에 따라 B 모듈이 조건을 탐침하고 A로 보내거나 제3의 공간으로 보내고 싶은 것이다.

쉽게 생각하면 모든 request 정보가 들어있는 request_rec을 복제하거나 변조하는 방법을 취할 수 있다. 이 때 mod_rewrite나, mod_proxy를 사용하거나 개조하는 방법도 검토할 수 있으나 막상 까보면 마땅치 않다.

그런데 이건 굉장한 수고로움이다. 게다가 memcpy 도 발생한다.

아파치 모듈의 후킹 구조를 생각하면 이렇게 수고롭게 구현할 필요가 없다.

가장 우아한 후킹 구조 중 하나인 리눅스 커널의 net filter 처럼 이해하면 된다.

1

서로 다른 모듈은 같은 핸들러 이름을 사용할 수 있다.

예컨데 A와 B는 아파치 설정에서 같은 핸들러 명을 사용할 수 있다.

SetHandler my-handler

이렇게 하고 A와 B 모듈의 후킹 펑션에 둘 다 쓴다.

if (strcmp(r->handler, “my-handler”)) {
    return DECLINED;
}

2

자 이제 후커가 둘이 됐는데 뭐가 먼저 호출 될 것인가?

후킹 우선 순위를 정할 수 있다. 후킹 펑션을 등록할 때 우선순위 파라미터가 있다.

ap_hook_handler(syrupad_gw_handler, NULL, NULL, APR_HOOK_LAST);

보통은 MIDDLE만 쓴다.

3

테스트 해보면 둘 중 한 놈만 호출되고 끝이다. LAST는 호출되지 않는다.

이유는 return OK 때문이다.

return OK는 http 200 리턴을 의미하지 않는다. 리퀘스트 처리를 끝냈다는 것을 의미하므로 아파치는 더 이상 후킹 리스트를 뒤지지 않고 끝낸다.

return DECLINED를 호출하면 아파치가 후킹 펑션 리스트를 한 칸 또 전진 시킨다.

이제 마침내 APR_HOOK_LAST에 도달해 핸들러 이름을 보고 후킹 펑션을 실행한다.

LAST의 리턴값은 OK가 되어야 한다. 그렇지 않으면 아파치가 후킹을 비정상으로 보고 아무것도 핸들링 하지 못했다고 판단하여 404를 리턴할 것이다.





공유하기













[t:/] is not "technology - root". dawnsea, rss